import time
import json
import webapp2

from webapp2_extras.i18n import gettext as _

from google.appengine.api import users
from apnetmodels.basicmodels import immeuble, budget_item
from common import functions
from wtforms.ext.appengine.db import model_form
from wtforms.fields import TextField
from wtforms import validators

from BaseHandler import BaseHandler

class BudgetItem(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(BudgetItem, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {
                       'immeuble': _('Tenement'), 'period': _('Account Period'), 'expenditure': _('Expenditure'),
                       'subaccount': _('Subaccount'), 'charges_key': _('Charges key'), 'amount': _('Amount'),
                       'state': _('State'), 'bubget_tag': _('Budget tag'), 'type': _('Type'), 'summary_amount': _('Summary amount'),
                       'summary_amount_cash': _('Summary cash amount'), 'amount_budget': _('Budget amount')
                       }
    
    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)
    
    def op_list_json_regular(self, *args, **kwargs):
        self.op_list_json(self, *args, **kwargs)
    def op_list_json_additional(self, *args, **kwargs):
        self.op_list_json(self, *args, **kwargs)
    def op_sum_json_regular(self, *args, **kwargs):
        self.op_sum_json(self, *args, **kwargs)
    def op_sum_json_additional(self, *args, **kwargs):
        self.op_sum_json(self, *args, **kwargs)
    
    def op_list(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        template_values = {
                           'title': _('Budget. %s' % imm.name),
                           'header': _('%s. Budget.' % imm.name),
                           'app_user': self.au,
                           'immeuble': imm,
                           'lurl': users.create_logout_url('/'),
                           'section': 'creation',
                           'leftmenu': 'budgets',
                           'fields': self.fields
                           }

        template = self.jinja2.get_template('templates/budget_items_list.html')
        self.response.out.write(template.render(template_values))
    
    def op_list_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        budget_type = None
        command = kwargs.get('command', None)
        if command == 'list_json_regular':
            budget_type = 'Regular'
        if command == 'list_json_additional':
            budget_type = 'Additional'
        
        budget_items = imm.budget_item_set.filter('state =', 'Not approved').filter('type = ', budget_type).order('period').order('charges_key').run()
        bi = []
        for b in budget_items:
            bi.append([unicode(b.period), unicode(b.expenditure), unicode(b.charges_key), str(functions.CurrencyFormat(b.amount)), str(b.key().id())])
        ret = {}
        ret['aaData'] = bi
        self.response.out.write(json.dumps(ret))
  
  
    def op_sum_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
            
        budget_type = None
        command = kwargs.get('command', None)
        if command == 'sum_json_regular':
            budget_type = 'Regular'
        if command == 'sum_json_additional':
            budget_type = 'Additional'

        sum_res = []
        for p in imm.period_concept_set.filter('closed =', False).order('date_start').run():
            if budget_type:
                sum_res.append(('<nobr>' + unicode(p) + '</nobr>', functions.CurrencyFormat(p.get_budget_sum(budget_type))))
            else:
                sum_res.append(('<nobr>' + unicode(p) + '</nobr>', functions.CurrencyFormat(p.get_budget_sum()), functions.CurrencyFormat(p.get_fundraising_sum()), 0, str(p.key().id())))
  
        ret = {}
        ret['aaData'] = sum_res
        self.response.out.write(json.dumps(ret))
    
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        
        ok_message = ''
        alert_message = ''
        
        BudgetItemForm = model_form(budget_item, exclude=['immeuble', 'state', 'bubget_tag', 'lastchange_by', 'lastchange_date'])
        setattr(BudgetItemForm, 'charges_key', TextField(u'Charges key', [validators.required(),]))
        setattr(BudgetItemForm, 'expenditure', TextField(u'Expenditure', [validators.required(),]))
        BudgetItemForm.period.creation_counter = 1
        BudgetItemForm.expenditure.creation_counter = 2
        BudgetItemForm.charges_key.creation_counter = 3
        BudgetItemForm.amount.creation_counter = 4
        
        if self.request.method == 'GET':
            form = BudgetItemForm()
            form['period'].query =  imm.period_concept_set.filter('closed =', False).order('date_start')
               
        if self.request.method == 'POST':
            post_obj = self.request.POST
            
            ck_list = imm.get_charges_key_list()
            exists = False
            for c in ck_list:
                if str(c) == post_obj['charges_key']:
                    post_obj['charges_key'] = c
                    exists = True
                    break
            if exists is False:
                post_obj['charges_key'] = ''
            
            exp_list = imm.get_exp_list()
            exists = False
            for e in exp_list:
                if str(e) == post_obj['expenditure']:
                    post_obj['expenditure'] = e
                    exists = True
                    break
            if exists is False:
                post_obj['expenditure'] = ''
            
            form = BudgetItemForm(post_obj)
            
            form['period'].query =  imm.period_concept_set.filter('closed =', False).order('date_start')
            
            if form.validate():
                save = True
                bi = imm.budget_item_set.filter('period =', form['period'].data).filter('expenditure =', form['expenditure'].data).filter('charges_key =', form['charges_key'].data).get()    
                if bi:
                    save = False
                    alert_message = _('Budget item already added.')
                if save:    
                    new_bi = budget_item(lastchange_by = self.au, 
                                         immeuble = imm, 
                                         period = form['period'].data,
                                         expenditure = form['expenditure'].data,
                                         charges_key = form['charges_key'].data,
                                         amount = form['amount'].data,
                                         type = form['type'].data,
                                         )
                    new_bi.put()
                    while not new_bi.is_saved():
                        time.sleep(2)
                    
                    ok_message = _('Budget item was added.')
        
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields, 'alert_message': alert_message }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_edit(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        bi_id = kwargs.get('bi_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return    
        bi_obj = budget_item.get_by_id(int(bi_id))
        if not bi_obj: 
            self.redirect(webapp2.uri_for('mainpage'))
            return    
        
        ok_message = ''
        
        BudgetItemForm = model_form(budget_item, exclude=['immeuble', 'type', 'state', 'bubget_tag', 'lastchange_by', 'lastchange_date'])
        setattr(BudgetItemForm, 'charges_key', TextField(u'Charges key', [validators.required(),]))
        setattr(BudgetItemForm, 'expenditure', TextField(u'Expenditure', [validators.required(),]))
        BudgetItemForm.period.creation_counter = 1
        BudgetItemForm.expenditure.creation_counter = 2
        BudgetItemForm.charges_key.creation_counter = 3
        BudgetItemForm.amount.creation_counter = 4

        if self.request.method == 'GET':
            form = BudgetItemForm(obj = bi_obj)
            form['period'].query = imm.period_concept_set.filter('closed =', False).order('date_start')
            
        if self.request.method == 'POST':
            post_obj = self.request.POST
            
            ck_list = imm.get_charges_key_list()
            exists = False
            for c in ck_list:
                if str(c) == post_obj['charges_key']:
                    post_obj['charges_key'] = c
                    exists = True
                    break
            if exists is False:
                post_obj['charges_key'] = ''
            
            exp_list = imm.get_exp_list()
            exists = False
            for e in exp_list:
                if str(e) == post_obj['expenditure']:
                    post_obj['expenditure'] = e
                    exists = True
                    break
            if exists is False:
                post_obj['expenditure'] = ''
            
            form = BudgetItemForm(post_obj)
            
            form['period'].query = imm.period_concept_set.filter('closed =', False).order('date_start')
            
            if form.validate():
                form.populate_obj(bi_obj)
                bi_obj.lastchange_by = self.au 
                
                bi_obj.put()
                
                ok_message = _('Budget item was saved.')
        
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields}
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_delete(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        bi_id = kwargs.get('bi_id', -1)
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        inv = budget_item.get_by_id(int(bi_id))
        if not inv:
            self.redirect(webapp2.uri_for('mainpage'))
            return
            
        ok_message = ''
        alert_message = ''
        
        if self.request.method == 'GET':
            alert_message = _('Are you sure you want to delete %s?' % inv)
            
        if self.request.method == 'POST':
            inv1 = inv
            inv.delete()
            while not inv1 is None:
                inv1 = budget_item.get_by_id(int(bi_id))
                time.sleep(1)
            ok_message = _('Budget item was deleted.')
                
        template_values = {
            'ok_message': ok_message,
            'alert_message': alert_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
